package android.framework.binding;

import java.util.ArrayList;


public class BindableList<T extends IObservable<Object>> extends ArrayList<T> implements IBindableList<T>, IObserver<Object>{

	private static final long serialVersionUID = 1L;
	private long lastActionId = -1;
	
	private ListMultiBindingAdapter<T> multiBindingAdapter = new ListMultiBindingAdapter<T>();
	
	public boolean onListChanged(T item, ListChangeOperation changeOperation, long actionId) {
		if(actionId > lastActionId){
			this.lastActionId = actionId;
			applyChanges(item, changeOperation, actionId);
			return true;
		}
		return false;
	}
	private void applyChanges(T item, ListChangeOperation changeOperation, long actionId) {
		switch (changeOperation) {
			case Add:
				super.add(item);
				break;
	
			case Remove:
				super.remove(item);
				break;
		case Changed:
			break;
		default:
			break;
		}
		notifyListener(item, changeOperation, actionId);
	}
	
	public boolean add(T item){
		item.addListener(this);
		boolean result = super.add(item);
		lastActionId = Binding.getNextActionId();
		notifyListener(item, ListChangeOperation.Add, lastActionId);
		return result;
	}
	
	public boolean remove(T item){
		item.removeListener(this);
		boolean result = super.remove(item);
		lastActionId = Binding.getNextActionId();
		notifyListener(item, ListChangeOperation.Remove, lastActionId);
		return result;
	}
	
	public void addListener(IListObserver<T> listener) {
		multiBindingAdapter.addObserver(listener);
	}
	public void removeListener(IListObserver<T> listener) {
		multiBindingAdapter.removeObserver(listener);
	}
	public void setListener(ListMultiBindingAdapter<T> listener) {
		multiBindingAdapter = listener;
	}

	protected void notifyListener(T item, ListChangeOperation operation){
		lastActionId = Binding.getNextActionId();
		notifyListener(item, operation, lastActionId);
	}
	
	private void notifyListener(T item, ListChangeOperation operation, long actionId){
		if(multiBindingAdapter != null){
			multiBindingAdapter.onListChanged(item, operation, actionId);
		}
	}
	public boolean notifyChanges(Object value, long actionId) {
		notifyListener(null, ListChangeOperation.Changed, actionId);
		return true;
	}

}
